<template>
  <view
    class="uni-easyinput"
    :class="{ 'uni-easyinput-error': msg }"
    :style="{ color: inputBorder && msg ? '#dd524d' : styles.color }"
  >
    <view
      class="uni-easyinput__content"
      :class="{
        'is-input-border': inputBorder,
        'is-input-error-border': inputBorder && msg,
        'is-textarea': type === 'textarea',
        'is-disabled': disabled,
      }"
      :style="{
        'border-color': inputBorder && msg ? '#dd524d' : styles.borderColor,
        'background-color': disabled ? styles.disableColor : '',
      }"
    >
      <uni-icons
        v-if="prefixIcon"
        class="content-clear-icon"
        :type="prefixIcon"
        color="#c0c4cc"
        @click="onClickIcon('prefix')"
      ></uni-icons>
      <textarea
        v-if="type === 'textarea'"
        class="uni-easyinput__content-textarea"
        :class="{ 'input-padding': inputBorder }"
        :name="name"
        :value="val"
        :placeholder="placeholder"
        :placeholderStyle="placeholderStyle"
        :disabled="disabled"
        :maxlength="inputMaxlength"
        :focus="focused"
        :autoHeight="autoHeight"
        @input="onInput"
        @blur="onBlur"
        @focus="onFocus"
        @confirm="onConfirm"
      ></textarea>
      <input
        v-else
        :type="type === 'password' ? 'text' : type"
        class="uni-easyinput__content-input"
        :style="{
          'padding-right': type === 'password' || clearable || prefixIcon ? '' : '10px',
          'padding-left': prefixIcon ? '' : '10px',
        }"
        :name="name"
        :value="val"
        :password="!showPassword && type === 'password'"
        :placeholder="placeholder"
        :placeholderStyle="placeholderStyle"
        :disabled="disabled"
        :maxlength="inputMaxlength"
        :focus="focused"
        @focus="onFocus"
        @blur="onBlur"
        @input="onInput"
        @confirm="onConfirm"
      />
      <template v-if="type === 'password'">
        <uni-icons
          v-if="val != ''"
          class="content-clear-icon"
          :class="{ 'is-textarea-icon': type === 'textarea' }"
          :type="showPassword ? 'eye-slash-filled' : 'eye-filled'"
          :size="18"
          color="#c0c4cc"
          @click="onEyes"
        ></uni-icons>
      </template>
      <template v-else-if="suffixIcon">
        <uni-icons
          v-if="suffixIcon"
          class="content-clear-icon"
          :type="suffixIcon"
          color="#c0c4cc"
          @click="onClickIcon('suffix')"
        ></uni-icons>
      </template>
      <template v-else>
        <uni-icons
          class="content-clear-icon"
          :class="{ 'is-textarea-icon': type === 'textarea' }"
          type="clear"
          :size="clearSize"
          v-if="clearable && focused && val"
          color="#c0c4cc"
          @click="onClear"
        ></uni-icons>
      </template>
      <slot name="right"></slot>
    </view>
  </view>
</template>

<script>
/**
 * Field 输入框
 * @description 此组件可以实现表单的输入与校验，包括 "text" 和 "textarea" 类型。
 * @tutorial https://ext.dcloud.net.cn/plugin?id=21001
 * @property {String| Number} 	value 		输入内容
 * @property {String } 	type 							输入框的类型（默认text） password/text/textarea/..
 * 	@value text				文本输入键盘
 * 	@value textarea 	多行文本输入键盘
 * 	@value password 	密码输入键盘
 * 	@value number			数字输入键盘，注意iOS上app-vue弹出的数字键盘并非9宫格方式
 * 	@value idcard			身份证输入键盘，信、支付宝、百度、QQ小程序
 * 	@value digit			带小数点的数字键盘	，App的nvue页面、微信、支付宝、百度、头条、QQ小程序支持
 * @property {Boolean} 	clearable 				是否显示右侧清空内容的图标控件(输入框有内容，且获得焦点时才显示)，点击可清空输入框内容（默认true）
 * @property {Boolean} 	autoHeight 				是否自动增高输入区域，type为textarea时有效（默认true）
 * @property {String } 	placeholder 			输入框的提示文字
 * @property {String } 	placeholderStyle 	placeholder的样式(内联样式，字符串)，如"color: #ddd"
 * @property {Boolean} 	focus 						是否自动获得焦点（默认false）
 * @property {Boolean} 	disabled 					是否不可输入（默认false）
 * @property {Number } 	maxlength 				最大输入长度，设置为 -1 的时候不限制最大长度（默认140）
 * @property {String } 	confirmType 			设置键盘右下角按钮的文字，仅在type="text"时生效（默认done）
 * @property {Number } 	clearSize 				清除图标的大小，单位px（默认15）
 * @property {String} 	prefixIcon				输入框头部图标
 * @property {String} 	suffixIcon				输入框尾部图标
 * @property {Boolean} 	trim 							是否自动去除两端的空格
 * @value both	去除两端空格
 * @value left	去除左侧空格
 * @value right	去除右侧空格
 * @value start	去除左侧空格
 * @value end		去除右侧空格
 * @value all		去除全部空格
 * @value none	不去除空格
 * @property {Boolean} 	inputBorder 			是否显示input输入框的边框（默认false）
 * @property {Object} 	styles 						自定义颜色
 * @event {Function} 		input 						输入框内容发生变化时触发
 * @event {Function} 		focus 						输入框获得焦点时触发
 * @event {Function} 		blur 							输入框失去焦点时触发
 * @event {Function} 		confirm 					点击完成按钮时触发
 * @event {Function} 		iconClick 				点击图标时触发
 * @example <uni-easyinput v-model="mobile"></uni-easyinput>
 */
import UniIcons from '../uni-icons/uni-icons'
import { debounce, throttle } from './common.js'

export default {
  name: 'uni-easyinput',
  props: {
    name: String,
    value: [Number, String],
    type: {
      type: String,
      default: 'text',
    },
    clearable: {
      type: Boolean,
      default: true,
    },
    autoHeight: {
      type: Boolean,
      default: false,
    },
    placeholder: String,
    placeholderStyle: String,
    focus: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    maxlength: {
      type: [Number, String],
      default: 140,
    },
    confirmType: {
      type: String,
      default: 'done',
    },
    // 清除按钮的大小
    clearSize: {
      type: [Number, String],
      default: 15,
    },
    // 是否显示 input 边框
    inputBorder: {
      type: Boolean,
      default: true,
    },
    prefixIcon: {
      type: String,
      default: '',
    },
    suffixIcon: {
      type: String,
      default: '',
    },
    // 是否自动去除两端的空格
    trim: {
      type: [Boolean, String],
      default: true,
    },
    // 自定义样式
    styles: {
      type: Object,
      default() {
        return {
          color: '#333',
          disableColor: '#eee',
          borderColor: '#e5e5e5',
        }
      },
    },
  },
  components: {
    UniIcons,
  },
  data() {
    return {
      focused: false,
      errMsg: '',
      val: '',
      showMsg: '',
      border: false,
      isFirstBorder: false,
      showClearIcon: false,
      showPassword: false,
    }
  },
  computed: {
    msg() {
      return this.errorMessage || this.errMsg
    },
    // 因为uniapp的input组件的maxlength组件必须要数值，这里转为数值，给用户可以传入字符串数值
    inputMaxlength() {
      return Number(this.maxlength)
    },
  },
  watch: {
    value(newVal) {
      if (this.errMsg) this.errMsg = ''
      this.val = newVal
      if (this.form && this.formItem) {
        this.formItem.setValue(newVal)
      }
    },
    focus(newVal) {
      this.$nextTick(() => {
        this.focused = this.focus
      })
    },
  },
  created() {
    this.val = this.value
    this.form = this.getForm('uniForms')
    this.formItem = this.getForm('uniFormsItem')
    if (this.form && this.formItem) {
      if (this.formItem.name) {
        this.rename = this.formItem.name
        this.form.inputChildrens.push(this)
      }
    }
  },
  mounted() {
    // this.onInput = throttle(this.input, 500)
    this.$nextTick(() => {
      // setTimeout(()=>{
      // },1000)
      this.focused = this.focus
    })
  },
  methods: {
    /**
     * 初始化变量值
     */
    init() {},
    onClickIcon(type) {
      this.$emit('iconClick', type)
    },
    /**
     * 获取父元素实例
     */
    getForm(name = 'uniForms') {
      let parent = this.$parent
      let parentName = parent.$options.name
      while (parentName !== name) {
        parent = parent.$parent
        if (!parent) return false
        parentName = parent.$options.name
      }
      return parent
    },

    onEyes() {
      this.showPassword = !this.showPassword
    },
    onInput(event) {
      let value = event.detail.value
      // 判断是否去除空格
      if (this.trim) {
        if (typeof this.trim === 'boolean' && this.trim) {
          value = this.trimStr(value)
        }
        if (typeof this.trim === 'string') {
          value = this.trimStr(value, this.trim)
        }
      }
      if (this.errMsg) this.errMsg = ''
      this.val = value
      this.$emit('input', value)
    },

    onFocus(event) {
      // this.focused = true;
      this.$emit('focus', event)
    },
    onBlur(event) {
      let value = event.detail.value
      // setTimeout(() => {
      // this.focused = false;
      // }, 100);
      this.$emit('blur', event)
    },
    onConfirm(e) {
      this.$emit('confirm', e.detail.value)
    },
    onClear(event) {
      this.val = ''
      this.$emit('input', '')
    },
    fieldClick() {
      this.$emit('click')
    },
    trimStr(str, pos = 'both') {
      if (pos === 'both') {
        return str.trim()
      } else if (pos === 'left') {
        return str.trimLeft()
      } else if (pos === 'right') {
        return str.trimRight()
      } else if (pos === 'start') {
        return str.trimStart()
      } else if (pos === 'end') {
        return str.trimEnd()
      } else if (pos === 'all') {
        return str.replace(/\s+/g, '')
      } else if (pos === 'none') {
        return str
      }
      return str
    },
  },
}
</script>

<style lang="scss" scoped>
.uni-easyinput {
  /* #ifndef APP-NVUE */
  width: 100%;
  /* #endif */
  flex: 1;
  position: relative;
  // padding: 16px 14px;
  text-align: left;
  color: #333;
  font-size: 14px;
}

.uni-easyinput__content {
  flex: 1;
  /* #ifndef APP-NVUE */
  width: 100%;
  display: flex;
  box-sizing: border-box;
  min-height: 36px;
  /* #endif */
  flex-direction: row;
  align-items: center;
}

.uni-easyinput__content-input {
  /* #ifndef APP-NVUE */
  width: auto;
  /* #endif */
  position: relative;
  overflow: hidden;
  flex: 1;
  line-height: 2;
  font-size: 14px;
  // padding-right: 10px;
}

.is-textarea {
  align-items: flex-start;
}

.is-textarea-icon {
  margin-top: 5px;
}

.uni-easyinput__content-textarea {
  position: relative;
  overflow: hidden;
  flex: 1;
  line-height: 1.5;
  font-size: 14px;
  padding-top: 6px;
  padding-bottom: 10px;
  height: 80px;
  /* #ifndef APP-NVUE */
  min-height: 80px;
  width: auto;
  /* #endif */
}

.input-padding {
  padding-left: 10px;
}

.content-clear-icon {
  padding: 0 5px;
}

.label-icon {
  margin-right: 5px;
  margin-top: -1px;
}

// 显示边框
.is-input-border {
  /* #ifndef APP-NVUE */
  display: flex;
  box-sizing: border-box;
  /* #endif */
  flex-direction: row;
  align-items: center;
  border: 1px solid $uni-border-color;
  border-radius: 4px;
}

.uni-easyinput__right {
  // margin-left: 5px;
}

// 必填
.is-required {
  color: $uni-color-error;
}

.uni-error-message {
  position: absolute;
  bottom: -17px;
  left: 0;
  line-height: 12px;
  color: $uni-color-error;
  font-size: 12px;
  text-align: left;
}

.uni-error-msg--boeder {
  position: relative;
  bottom: 0;
  line-height: 22px;
}

.is-input-error-border {
  border-color: $uni-color-error;
}

.uni-easyinput--border {
  margin-bottom: 0;
  padding: 10px 15px;
  // padding-bottom: 0;
  border-top: 1px #eee solid;
}

.uni-easyinput-error {
  padding-bottom: 0;
}

.is-first-border {
  /* #ifndef APP-NVUE */
  border: none;
  /* #endif */
  /* #ifdef APP-NVUE */
  border-width: 0;
  /* #endif */
}

.is-disabled {
  background-color: #eee;
}
</style>
